package implementations;

import java.util.ArrayList;

import clientController.Client;

import global.GlobalVars;
import interfaces.IBoard;
import interfaces.IPlayer;
import interfaces.IPoint;
import interfaces.IShip;

public class PlayerImpl implements IPlayer
{

	private String name;
	private ArrayList<IShip> myShips;
	private IBoard myBoard;
	private IBoard enemyBoard;
	private int type;
	private int id;

	public int getId()
	{
		return id;
	}

	private boolean plantableShips;

	public PlayerImpl(String theName, int type, int id)
	{
		this.id = id;
		this.type = type;
		// this.id=id;
		// this.type=type;
		// if (type == 2)
		// {
		//
		// Client.createClient(id);
		// } else if (type == 1)
		//
		// {
		//
		// Client.createClient(id);
		// }

		myShips = GlobalVars.ships;
		System.out.println("The ships were loaded!!");
		System.out.println("First ship:" + myShips.get(0).getMainPoint().getX()
				+ " " + myShips.get(0).getMainPoint().getY());
		name = theName;
		myBoard = new BoardImpl();
		enemyBoard = new BoardImpl();
	}

	@Override
	public void attack(IPoint point)
	{
		// TODO Send the point coordonates to the enemy and wait
		// if(this.type==1)
		// Server.ServerAttack();
		// Client.clientAttack(id, point);
	}

	@Override
	public void getAttackResponse(IPoint point, boolean response)
	{
		char[][] grid = enemyBoard.getGrid();
		System.out.println("REsponse from func!" + response);
		if (response == true)
		{
			grid[point.getX()][point.getY()] = GlobalVars.enemyBoardHit;
		} else
		{

			grid[point.getX()][point.getY()] = GlobalVars.enemyBoardMiss;
		}

		// TODO Auto-generated method stub

	}

	@Override
	public boolean deffend(IPoint point)
	{
		// TODO: add to database!!!
		char[][] grid = myBoard.getGrid();
		boolean ok = false;
		if (grid[point.getX()][point.getY()] != GlobalVars.myShipPart
				&& grid[point.getX()][point.getY()] != GlobalVars.myShipPartHitted)
		{
			ok = false;
			grid[point.getX()][point.getY()] = GlobalVars.myBoardMiss;
		} else
		{
			ok = true;
			grid[point.getX()][point.getY()] = GlobalVars.myShipPartHitted;
		}
		return ok;

		// sendDeffendResponse(point, ok);
	}

	// @Override
	// public void sendDeffendResponse(IPoint point, boolean response) {
	// // TODO ADD TO DATABASE!!!
	//
	// }

	private boolean checkPointOnGrid(IPoint point)
	{
		if (point.getX() < 0 || point.getX() >= GlobalVars.gridXSize
				|| point.getY() < 0 || point.getY() >= GlobalVars.gridYSize)
			return false;

		else
			return true;
	}

	public String getName()
	{
		return name;
	}

	public ArrayList<IShip> getMyShips()
	{
		return myShips;
	}

	public IBoard getMyBoard()
	{
		return myBoard;
	}

	public IBoard getEnemyBoard()
	{
		return enemyBoard;
	}

	private boolean PlantShip(IShip ship)
	{
		boolean ok = true;
		char[][] grid = myBoard.getGrid();
		char[][] newGrid = copyGrid(myBoard.getGrid());
		ArrayList<IPoint> points = ship.getPoints();
		for (int i = 0; i < points.size(); i++)
		{
			IPoint point = points.get(i);

			if (checkPointOnGrid(point))
			{
				char value = grid[point.getX()][point.getY()];
				if (!(value == GlobalVars.waves || value == GlobalVars.myShipPart)) // 96=valuri
				// 97=nava!!!
				{
					newGrid[point.getX()][point.getY()] = GlobalVars.myShipPart; // 97=nava!!!
				} else
				{
					ok = false;
					break;
				}

			} else
			{
				ok = false;
				break;
			}
		}
		if (ok == true)
		{
			myBoard.setGrid(copyGrid(newGrid));
			recalculateGrid();
		}
		return ok;
	}

	private char[][] copyGrid(char[][] newGrid)
	{
		char[][] agrid = new char[GlobalVars.gridXSize][GlobalVars.gridYSize];
		for (int i = 0; i < GlobalVars.gridXSize; i++)
		{
			for (int j = 0; j < GlobalVars.gridYSize; j++)
			{
				agrid[i][j] = newGrid[i][j];
			}
		}
		return agrid;

	}

	private void recalculateGrid()
	{
		for (int i = 0; i < GlobalVars.gridXSize; i++)
		{
			for (int j = 0; j < GlobalVars.gridYSize; j++)
			{
				if (myBoard.getGrid()[i][j] == GlobalVars.myShipPart) // 97=barca
																		// 96=valuri
				{
					if (i - 1 >= 0
							&& myBoard.getGrid()[i - 1][j] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i - 1][j] = GlobalVars.waves;
					}
					if (i + 1 < GlobalVars.gridXSize
							&& myBoard.getGrid()[i + 1][j] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i + 1][j] = GlobalVars.waves;
					}
					if (j - 1 >= 0
							&& myBoard.getGrid()[i][j - 1] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i][j - 1] = GlobalVars.waves;
					}
					if (j + 1 < GlobalVars.gridYSize
							&& myBoard.getGrid()[i][j + 1] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i][j + 1] = GlobalVars.waves;
					}
					// //////////////////////////////
					if (i - 1 >= 0
							&& j - 1 >= 0
							&& myBoard.getGrid()[i - 1][j - 1] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i - 1][j - 1] = GlobalVars.waves;
					}
					if (j + 1 < GlobalVars.gridYSize
							&& i - 1 >= 0
							&& myBoard.getGrid()[i - 1][j + 1] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i - 1][j + 1] = GlobalVars.waves;
					}
					if (j - 1 >= 0
							&& i + 1 < GlobalVars.gridXSize
							&& myBoard.getGrid()[i + 1][j - 1] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i + 1][j - 1] = GlobalVars.waves;
					}
					if (j + 1 < GlobalVars.gridYSize
							&& i + 1 < GlobalVars.gridXSize
							&& myBoard.getGrid()[i + 1][j + 1] != GlobalVars.myShipPart)
					{
						myBoard.getGrid()[i + 1][j + 1] = GlobalVars.waves;
					}

				}
			}
		}
	}

	@Override
	public void setNextShipOnBoard(IPoint mainPoint) throws Exception
	{

		System.out.println("Before:");
		for (int i = 0; i < GlobalVars.gridXSize; i++)
		{
			for (int j = 0; j < GlobalVars.gridYSize; j++)
			{
				System.out.print(this.myBoard.getGrid()[i][j] + " ");
			}
			System.out.println();
		}
		if (!checkPointOnGrid(mainPoint))
			throw new Exception("The point is out of the GRID!");
		IShip ship = getNextPlantableShip();
		if (ship != null)
		{
			ship.setMainPoint(mainPoint);

			if (!PlantShip(ship))
			{
				ship.setIsPlanted(false);
				throw new Exception("You cannot plant the ship there!");
			} else
			{
				ship.setIsPlanted(true);
			}

		}

		System.out.println("After:");
		for (int i = 0; i < GlobalVars.gridXSize; i++)
		{
			for (int j = 0; j < GlobalVars.gridYSize; j++)
			{
				System.out.print(this.myBoard.getGrid()[i][j] + " ");
			}
			System.out.println();
		}
		System.out.println("========================================");

	}

	public boolean hasPlantableShips()
	{

		IShip ship = getNextPlantableShip();
		if (ship == null)
			return false;
		else
			return true;

	}

	public IShip getNextPlantableShip()
	{
		for (int i = 0; i < myShips.size(); i++)
		{
			IShip ship = myShips.get(i);
			if (!ship.isPlanted())
			{
				return ship;
			}
		}
		return null;
	}

	public int getType()
	{
		return type;
	}

	public void setType(int type)
	{
		this.type = type;
	}

	@Override
	public boolean isStillFighting()
	{
		boolean ok = false;
		for(IShip ship:myShips)
		{
			if(ship.isAlive())
			{
				ok=true;
				break;
			}
		}
		
		
		return ok;
	}
}
